home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-19 | 3.5 KB | 95 lines | [TEXT/CWIE] |
- /*
- Problem 09 - State Machine
-
- type GetNextCharProc = function( curstate: UInt32 ): UInt32;
-
- procedure StateMachineInit( var state_machine: Handle; states: UInt32; chars:
- UInt32 );
- procedure AddTransition( state_machine: Handle; state1, state2: UInt32;
- first_char, last_char: UInt32 );
- procedure RunStateMachine( state_machine: Handle; start_state: UInt32;
- GetNextChar: GetNextCharProc; var stop_state: UInt32 );
-
- This problem requires you to maintain and operate a state machine, consisting
- of rules that change the current machine state based on the current input. Our
- state machines do not require that you produce any output other than the
- machine state.
-
- StateMachineInit creates a new, empty state machine ready to accept state
- transitions, and containing states states (numbers 1 to states) and chars
- characters (numbered 1 to chars). All the state machine information must be
- stored in the real Mac memory manager handle - it will be disposed with
- DisposeHandle and that must release all memory, so dont store any extra
- information outside the handle. Also, you must be able to deal with having
- multiple state machine instantiated simultaneously.
-
- AddTransition adds a transition from state1 to state2 for characters between
- (inclusive) first_char and last_char. When you get to state1 and get a
- character between first_char and last_char you should proceed to state2. The
- new transition overrides and previous transitions for these characters from
- state1 (ie, if you get transition 1->2 for chars 1-10, and then 1->3 for chars
- 5-6, you now have transition 1->2 for chars 1-4 and 7-10 and transition 1->3
- for chars 5-6).
-
- RunStateMachine starts in start_state and calls GetNextChar repeatedly until
- either it returns 0 or until it returns a character for which there is no
- transition at the current state. Each time GerNewChar supplies a character,
- the current state is updated based on the transition rule that applies to that
- combination of current state and current input. When GetNextChar supplies a
- state for which no transition rule exists, the state machine halts and the
- final state is returned in stop_state.
- */
-
- #include "Solution.h"
-
- // Fill in your solution and then submit this folder
-
- // Team Name: Three And One!
-
- struct Header {
- int numTransitions;
- };
-
- struct Transition {
- UInt32 state1; UInt32 state2; UInt32 first_char; UInt32 last_char;
- };
-
- static UInt32 NextState(int numTransitions, const Transition transitions[], UInt32 state, UInt32 character)
- {
- while (numTransitions != 0) {
- const Transition& t = transitions[--numTransitions];
- if (t.state1 == state && t.first_char <= character && t.last_char >= character)
- return t.state2;
- }
- return 0;
- }
-
- pascal void StateMachineInit( Handle *state_machine, UInt32 /*states*/, UInt32 /*chars*/)
- {
- *state_machine = NewHandleClear(sizeof(Header));
- }
-
- pascal void AddTransition( Handle state_machine, UInt32 state1, UInt32 state2, UInt32 first_char, UInt32 last_char )
- {
- Transition t = { state1, state2, first_char, last_char };
- PtrAndHand(&t, state_machine, sizeof(t));
- (**(Header**)state_machine).numTransitions += 1;
- }
-
- pascal void RunStateMachine( Handle state_machine, UInt32 state, GetNextCharProc GetNextChar, UInt32 *stop_state)
- {
- HLock(state_machine);
- while (1) {
- UInt32 character = GetNextChar(state_machine, state);
- if (character == 0)
- break;
- UInt32 nextState = NextState((**(Header**)state_machine).numTransitions,
- (Transition *)(*state_machine + sizeof(Header)), state, character);
- if (nextState == 0)
- break;
- state = nextState;
- }
- HUnlock(state_machine);
- *stop_state = state;
- }
-